use sea_orm::{
    ColumnTrait, DatabaseConnection, DbErr, DeleteResult, EntityTrait, PaginatorTrait, QueryFilter,
    QueryOrder,
};
use sky_common::constant::status;
use sky_pojo::{dto::category::CategoryPageQueryDTO, entities::category, vo::PageResult};

pub async fn insert(
    db: DatabaseConnection,
    category: category::ActiveModel,
) -> Result<category::Model, DbErr> {
    let result = category::Entity::insert(category)
        .exec_with_returning(&db)
        .await?;

    Ok(result)
}

pub async fn page_query(
    db: DatabaseConnection,
    query: CategoryPageQueryDTO,
) -> Result<PageResult<category::Model>, DbErr> {
    let mut stmt = category::Entity::find();

    if let Some(r#type) = query.r#type {
        stmt = stmt.filter(category::Column::Type.eq(r#type));
    }

    // 条件过滤
    if let Some(name) = query.name {
        if !name.is_empty() {
            stmt = stmt.filter(category::Column::Name.contains(&name));
        }
    }

    // 总记录数
    let total: u64 = stmt.clone().count(&db).await?;

    // 分页数据
    let category_vec: Vec<category::Model> = stmt
        .order_by_asc(category::Column::Sort)
        .order_by_desc(category::Column::CreateTime)
        .paginate(&db, query.page_size.try_into().unwrap())
        .fetch_page((query.page - 1).try_into().unwrap())
        .await?;

    Ok(PageResult {
        total,
        records: category_vec,
    })
}

pub async fn modify_by_id(
    db: DatabaseConnection,
    category_id: i64,
    category: category::ActiveModel,
) -> Result<category::Model, DbErr> {
    let result = category::Entity::update(category)
        .filter(category::Column::Id.eq(category_id))
        .exec(&db)
        .await?;
    Ok(result)
}

// dangerous
pub async fn delete_by_id(db: DatabaseConnection, category_id: i64) -> Result<DeleteResult, DbErr> {
    let result = category::Entity::delete_by_id(category_id)
        .exec(&db)
        .await?;

    Ok(result)
}

pub async fn list_by_type(
    db: DatabaseConnection,
    r#type: i32,
) -> Result<Vec<category::Model>, DbErr> {
    let result = category::Entity::find()
        .filter(category::Column::Status.eq(status::ENABLE))
        .filter(category::Column::Type.eq(r#type))
        .order_by_asc(category::Column::Sort)
        .order_by_desc(category::Column::CreateTime)
        .all(&db)
        .await?;
    Ok(result)
}
